package cn.tellfish.studydemo.thread;

import java.util.Collections;
import java.util.LinkedList;
import java.util.List;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.LinkedBlockingQueue;

public class MyFixedSizeThreadPool {

    private BlockingQueue<Runnable> taskQueue;

    private List<Worker> workers;
    private boolean working = true;

    public MyFixedSizeThreadPool(int poolSize, int taskQueueSize) {

        this.taskQueue = new LinkedBlockingQueue<>(taskQueueSize);
        this.workers = Collections.synchronizedList(new LinkedList<>());

        //创建线程
        for (int i = 0; i < poolSize; i++) {
            Worker w = new Worker(this);
            this.workers.add(w);
            w.start();
        }
    }

    public boolean submit(Runnable task) {
        return this.taskQueue.offer(task);
    }

    public void shutDown() {
        if (this.working) {
            this.working = false;
        }
        for (Worker worker : this.workers) {
            if (worker.getState().equals(Thread.State.BLOCKED) ||
                    worker.getState().equals(Thread.State.WAITING)) {
                worker.interrupt();
            }
        }
    }

    private class Worker extends Thread {

        private final MyFixedSizeThreadPool pool;

        Worker(MyFixedSizeThreadPool pool) {
            super();
            this.pool = pool;
        }

        private volatile int taskCount = 0;

        @Override
        public void run() {
            while (this.pool.working || this.pool.taskQueue.size() > 0) {
                Runnable take = null;
                try {
                    take = this.pool.taskQueue.take();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                if (take != null) {
                    try {
                        take.run();
                        System.out.println(Thread.currentThread().getName() + "完成第" + (++taskCount) + "个任务");
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                }
            }
            System.out.println(Thread.currentThread().getName() + "结束");
        }
    }

    public static void main(String[] args) {
        MyFixedSizeThreadPool pool = new MyFixedSizeThreadPool(3, 5);
        for (int i = 0; i < 5; i++) {
            pool.submit(() -> {
//                System.out.println(Thread.currentThread().getName() + "执行完成第");
                System.out.println("任务开始。。。");
                try {
                    Thread.sleep(2000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            });
        }
    }

}
